package com.raising.framework.websocket;

import com.raising.modules.websocket.entity.MsgBody;
import net.sf.json.JSONObject;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * webSocket服务端
 * @author GaoYuan
 * @date 2018/7/31 下午4:13
 */
@ServerEndpoint("/webSocket/chat/{roomId}/{userId}")
public class WsServer {

    /**
     * 使用map来收集session，key为roomId，value为同一个房间的用户集合
     * concurrentMap的key不存在时报错，不是返回null
     */
    public static final Map<String, Map<String,Session>> rooms = new ConcurrentHashMap();

    @OnOpen
    public void connect(@PathParam("roomId") String roomId, Session session,@PathParam("userId") String userId) throws Exception {
        // 将session按照房间名来存储，将各个房间的用户隔离
        if (!rooms.containsKey(roomId)) {
            // 创建房间不存在时，创建房间
            Map<String, Session> room = new ConcurrentHashMap<>();
            // 添加用户
            room.put(userId, session);
            rooms.put(roomId, room);
        } else {
            // 扫描并踢出重复登录的前用户
            removeSameUser(roomId, userId, session.getId());
            // 房间已存在，直接添加用户到相应的房间
            rooms.get(roomId).put(userId, session);
        }
        System.out.println("a client has connected!");
    }

    @OnClose
    public void disConnect(@PathParam("roomId") String roomId, Session session,@PathParam("userId") String userId) {
        rooms.get(roomId).remove(userId);
        System.out.println("a client has disconnected!");
    }

    /**
     * 接收消息 - 处理消息
     * @author GaoYuan
     * @date 2018/7/31 下午5:10
     */
    @OnMessage
    public void receiveMsg(@PathParam("roomId") String roomId,@PathParam("userId") String userId,
                           String msgBody, Session session) throws Exception {
        JSONObject jsonobject = JSONObject.fromObject(msgBody);
        MsgBody object= (MsgBody)JSONObject.toBean(jsonobject,MsgBody.class);
        // 此处应该有html过滤 TODO
        System.out.println(object.toString());
        if(object!=null && "1".equals(object.getUserId())){
            String msg = object.getContent();
            msg = "高元" + ":" + msg;
            // 接收到信息后进行广播
            broadcast(roomId, msg);
        }
    }

    /**
     * 按照房间名进行广播
     * @author GaoYuan
     * @date 2018/7/31 下午5:17
     */
    public static void broadcast(String roomId, String msg) throws Exception {
        Map<String,Session> map = rooms.get(roomId);

        //遍历map中的值
        for (Session session : map.values()) {
            session.getBasicRemote().sendText(msg);
        }
//        for (Map.Entry<String, Session> entry : map.entrySet()) {
//            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
//            entry.getValue().getBasicRemote().sendText(msg);
//        }
    }

    /**
     * 踢出重复登录的前用户
     * 相同roomId，相同userId，不同sessionId的用户
     * @author GaoYuan
     * @date 2018/7/31 下午5:27
     */
    public static void removeSameUser(String roomId,String userId,String sessionId) throws Exception{
        Map<String,Session> map = rooms.get(roomId);
        Iterator<Map.Entry<String, Session>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Session> entry = entries.next();
            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
            if(userId.equals(entry.getKey()) && !sessionId.equals(entry.getValue().getId())){
                // 找到重复的，给重复的页面发送数据提示
                entry.getValue().getBasicRemote().sendText("重复");
            }
        }
    }

}